import { createGlobalComponent } from '../createComponent.js'
import { isVideo, isImage, generateVideoPoster } from 'utils/utils.js'
import { message } from 'ant-design-vue'
import { OssUploadFile } from 'utils/oss.js'
import { downloadImg } from 'utils/file.js'
import preview from '../preview.vue'
export default {
  inheritAttrs: true,
  props: {
    w: {
      type: Number,
      default: 170
    },
    isText: {
      type: Boolean,
      default: false
    },
    text: {
      type: String,
      default: '上传'
    },
    showCount: {
      type: Number,
      default: 0
    },
    showUpload: {
      type: Boolean,
      default: true
    },
    isDragger: {
      type: Boolean,
      default: true
    },
    value: {
      type: Array,
      default: () => []
    },
    showDownload: {
      type: Boolean,
      default: true
    },
    limitNum: {
      type: Number,
      default: 30
    },
    size: {
      type: Number,
      default: 30
    },
    accept: {
      type: String,
      default: ''
    },
    listType: {
      type: String,
      default: 'text'
    },
    middle: {
      type: Boolean,
      default: false
    },
    small: {
      type: Boolean,
      default: false
    },
    xsmall: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: true
    },
    // 是否全局预览
    previewMountGlobal: {
      type: Boolean,
      default: false
    },
    us: {
      type: Boolean,
      default: false
    },
    type: {
      type: String,
      default: ''
    },
    isDrawing: {
      type: Boolean,
      default: false
    },
    isImageSwiper: {
      type: Boolean,
      default: false
    },
    swiperOption: {
      type: Object,
      default: () => {
        return {
          pagination: {
            el: '.swiper-pagination'
          }
        }
      }
    }
  },
  data() {
    return {
      loading: false,
      downloadImg,
      previewDom: null,
      oss: null,
      videoVisible: {
        visible: false,
        url: ''
      },
      state: {
        fileList: [],
        accept: '',
        isPreview: false,
        previewImage: '',
        inputPaste: null
      }
    }
  },
  computed: {
    fileList() {
      let arr = []
      const len = this.state.fileList.length
      if (len && this.showCount && len > this.showCount) {
        const fileList1 = [...this.state.fileList]
        arr = fileList1.splice(0, this.showCount)
      } else {
        arr = [...this.state.fileList]
      }
      return arr
    }
  },
  watch: {
    'state.fileList': {
      handler(val) {
        const isloading = val.some(item => !item.ossUrl)
        this.$emit('change', isloading, val)
        this.updateValue()
      },
      deep: true
    },
    listType: {
      handler(val) {
        if (val === 'picture-card' && !this.accept && this.type !== 'all') {
          this.state.accept = 'image/*'
        } else {
          this.state.accept = this.accept
        }
      },
      immediate: true
    },
    value: {
      handler(newValue, oldValue) {
        if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
          const fileList = []
          newValue &&
            newValue.forEach(item => {
              fileList.push({
                ...item,
                ...{
                  uid: item.uid || Math.random(),
                  ossUrl: item.ossUrl || '',
                  ossName: item.ossName || item.name || '',
                  ossType: item.ossUrl && this.getSuffix(item.ossUrl)
                }
              })
            })
          this.state.fileList = fileList
        }
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    videoVisibleCancel() {
      this.videoVisible.visible = false
      this.videoVisible.url = ''
    },
    getSuffix: url => {
      return url.substring(url.lastIndexOf('.') + 1)
    },
    getOssRegion() {
      if (this.us) {
        return 'oss-us-west-1'
      } else if (process.env.VUE_APP_MODE === 'production') {
        return 'oss-accelerate'
      } else {
        return 'oss-cn-hangzhou'
      }
    },
    replaceURL(url) {
      if (this.us) {
        return url.replace(
          'cs-oss-production.oss-us-west-1.aliyuncs.com',
          'cdn-review.cupshe.com'
        )
      } else if (process.env.VUE_APP_MODE === 'production') {
        return url.replace(
          'cs-scm.oss-accelerate.aliyuncs.com',
          'oss-scm-prod.kapeixi.cn'
        )
      }
      return url
    },
    beforeUpload(file, fileList) {
      return new Promise((resolve, reject) => {
        const isLmt = file.size / 1024 / 1024 < this.size
        if (!isLmt) {
          message.error('最大限制上传资源大小为 ' + this.size + 'MB!')
          reject(false)
          return
        }
        resolve(true)
      })
    },
    handlerChange(e) {
      this.customRequest(e.target.files)
      e.target.value = ''
    },
    closePreview() {
      this.state.isPreview = false
    },

    customRequest(files) {
      const fileList = Array.from(files)
      const count = this.limitNum - this.state.fileList.length
      if (this.state.fileList.length + fileList.length > this.limitNum) {
        message.error(
          '最多显示' + this.limitNum + `个文件,您当前只能选择${count}个文件上传`
        )
        return
      }
      fileList.map(async file => {
        const isValid = await this.beforeUpload(file, fileList)
        if (isValid) {
          file.uid = Math.random()
          file.ossName = file.name
          this.handleUpload(file)
        }
      })
    },
    // 上传文件
    async handleUpload(file) {
      this.state.fileList.push({
        uid: file.uid,
        ossName: file.name
      })

      const idx = this.state.fileList.findIndex(item => {
        return item.uid === file.uid
      })

      const region = this.getOssRegion()
      if (!this.oss) {
        this.oss = OssUploadFile.getInstance(region)
      }
      const { res } = await this.oss.put(file)
      if (res.status === 200) {
        const url = this.replaceURL(res.requestUrls[0])

        this.$set(this.state.fileList, idx, {
          ...this.state.fileList[idx],
          ...{
            uid: file.uid,
            ossName: file.name,
            ossType: url && this.getSuffix(url),
            ossUrl: url
          }
        })
        console.log(22, this.state.fileList)

        this.$forceUpdate()
      } else {
        this.onDelete(idx)
        console.log('图片上传失败')
        message.error('图片上传失败，请重试')
      }
    },
    async uploadToOss(file) {
      const region = this.getOssRegion()
      if (!this.oss) {
        this.oss = OssUploadFile.getInstance(region)
      }
      const { res } = await this.oss.put(file)

      return new Promise(resolve => {
        if (res.status === 200) {
          const url = this.replaceURL(res.requestUrls[0])
          resolve(url)
        } else {
          reject(res)
        }
      })
    },
    // 删除文件
    onDelete(index) {
      this.state.fileList.splice(index, 1)
      this.$emit('onDelete', index, this.state.fileList)
    },
    onDragEnd(evt) {
      evt.preventDefault()
      console.log('拖动前的索引 :' + evt.oldIndex)
      console.log('拖动后的索引 :' + evt.newIndex)
      const oldValue = this.state.fileList[evt.oldIndex]

      this.state.fileList.splice(evt.oldIndex, 1)
      this.state.fileList.splice(evt.newIndex, 0, oldValue)
      this.updateValue()
    },
    // 双向更新数据
    updateValue() {
      this.$emit('input', this.state.fileList)
    },
    dropEvent(e) {
      e.stopPropagation()
      e.preventDefault()
      this.customRequest(e.dataTransfer.files)
      console.log(e)
    },
    allowDrop(e) {
      e.stopPropagation()
      e.preventDefault()
    },
    // 复制粘贴图片
    pasteImg(e) {
      if (this.state.fileList.length >= this.limitNum) return

      const clipboardData = e.clipboardData || window.clipboardData
      console.log(clipboardData) // 查看clipboardData
      const items = clipboardData.items
      let file = null
      // 搜索剪切板items
      for (let i = 0; i < items.length; i++) {
        console.log(items[i])
        if (items[i].type.indexOf('image') !== -1) {
          file = items[i].getAsFile()
          // break
        } else {
          // clipboardData.clearData(items[i].type)
          const str = clipboardData.getData(items[i].type)
          console.log(str)
        }
      }
      if (!file) {
        message.error('请粘贴图片')
        return
      }
      this.customRequest([file])
    },
    mouseleave() {
      this.$refs.inputPaste && this.$refs.inputPaste?.blur()
    },
    mouseenter() {
      this.$refs.inputPaste && this.$refs.inputPaste?.focus()
    },
    async handleDrawImg(file, index) {
      const self = this
      this.$refs.sketchpadRef.open(file.ossUrl, async ({ blob }) => {
        const name =
          file.ossName.indexOf('.') > -1
            ? file.ossName
            : file.ossUrl?.split('/').pop()
        const imgFile = new File([blob], name, {
          type: blob.type
        })
        const url = await self.uploadToOss(imgFile)
        self.$set(self.state.fileList, index, {
          ...self.state.fileList[index],
          ...{
            uid: file.uid,
            ossName: file.ossName,
            ossType: url && self.getSuffix(url),
            ossUrl: url
          }
        })
        message.success('保存成功')
      })
    },
    handlePreview(file) {
      if (isVideo(file.ossUrl)) {
        this.videoVisible.url = file.ossUrl
        this.videoVisible.visible = true
        return
      }
      this.state.previewImage = file
      this.state.isPreview = true
      if (this.previewMountGlobal) {
        document.querySelector('.ant-modal-root.previewGlobal')?.remove()
        this.previewDom = createGlobalComponent(preview, {
          visible: this.state.isPreview,
          file: this.state.previewImage,
          fileList: this.state.fileList,
          className: 'previewGlobal',
          close: () => {
            this.state.isPreview = false
            this.previewDom.remove()
            this.previewDom = null
          }
        })
      }
    },
    isImage: isImage,
    isVideo: isVideo,
    generateVideoPoster: generateVideoPoster
  }
}
